﻿using System;
using System.Drawing;
using System.IO;
using System.Windows.Forms;
using DiffCalc;
using DigitalRune.Windows.TextEditor.Actions;
using EmbeddedSharp.Core;
using Gajatko.IniFiles.Light;
using WeifenLuo.WinFormsUI.Docking;
using Zove.DesignTime;
using Zove.Desktop.Tools;
using Zove.Desktop.Tools.Database;
using Zove.Runtime;
using Zove.Desktop.Resources.Tools;
using System.Collections.Generic;
using System.Configuration;
using EmbeddedSharp.Scripting;

namespace Zove.Desktop {
    public partial class Form1 : Form {

        private int untitledCount = 0;

        public string Status {
            get {
                return this.StatusBar.Text;
            }
            set {
                this.StatusBar.Text = value;
            }
        }

        public Form1() {
            InitializeComponent();

            this.WorkspaceWindowCollection = new WorkspaceWindowCollection();
            this.tsbNew.Click += new EventHandler(exitToolStripMenuItem_Click);
            this.tsbOpen.Click += new EventHandler(forEditToolStripMenuItem_Click);
            //this.tsbOpenForRun.Click += new EventHandler(forRunToolStripMenuItem_Click);
            this.tsbSave.Click += new EventHandler(saveToolStripMenuItem_Click);
            this.cmdDebug.Click += new EventHandler(runToolStripMenuItem1_Click);
            this.DragDrop += new DragEventHandler(Form1_DragDrop);
            this.DragEnter += new DragEventHandler(From1_DragEnter);

            // loads functions
            string str = ZoveDependencyManager.Instance.ToString();
            this.Load += new EventHandler(Form_Load);
            this.FormClosing += new FormClosingEventHandler(Form1_FormClosing);

            LoadFunctions();
        }

        private const string SETTING_PATTERN_MYDOCUMENTS = "$MyDocuments";

        private const string SETTING_PATTERN_PROGRAMFILES = "$ProgramFiles";

        private const string SETTING_PATTERN_WINDOWS = "$Windows";

        private const string SETTING_PATTERN_HOME = "$Home";

        private Dictionary<string, string> patterns;

        /// <summary>
        /// Initialize the patterns
        /// </summary>
        /// <returns></returns>
        public Dictionary<string, string> Patterns {
            get {
                if (patterns == null) {
                    patterns = new Dictionary<string, string>();

                    patterns.Add(SETTING_PATTERN_HOME,
                        Environment.GetFolderPath(
                        System.Environment.SpecialFolder.Desktop));
                    patterns.Add(SETTING_PATTERN_MYDOCUMENTS,
                        Environment.GetFolderPath(
                        System.Environment.SpecialFolder.MyDocuments));
                    patterns.Add(SETTING_PATTERN_PROGRAMFILES,
                        Environment.GetFolderPath(
                        System.Environment.SpecialFolder.ProgramFiles));
                }

                return patterns;
            }
        }

        private void LoadFunctions() {
            DirectoryInfo di;

            string path = DesktopUtils.FunctionPath;
            if (string.IsNullOrEmpty(path)) {
                di = new DirectoryInfo(Environment.CurrentDirectory);
            } else {
                foreach (string key in patterns.Keys) {
                    if (path.Contains(key)) {
                        path = path.Replace(key, patterns[key]);
                    }
                }

                di = new DirectoryInfo(path);
            }

            this.LoadFunctions(di);
        }

        private void LoadFunctions(DirectoryInfo di) {
            foreach (DirectoryInfo s in di.GetDirectories()) {
                this.LoadFunctions(s);
            }

            foreach (FileInfo fi in di.GetFiles("*.zoom")) {
                ZoomClass zc = ZoveDependencyManager.Instance.ClassLoader.LoadFromFile(fi.FullName);
            }
        }

        public DockPanel DockPanel {
            get {
                return this.dockPanel1;
            }
        }

        public void Form1_DragDrop(object sender, DragEventArgs e) {
            string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);

            foreach (string file in files) {
                if (file.EndsWith(".zoom")) {
                    OpenEditWindow(file);
                } else if (file.EndsWith(".zql")) {
                    OpenQueryWindow(file);
                }
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public QueryWindow OpenQueryWindow() {
            QueryWindow qw = new QueryWindow();
            this.InitQueryWindow(qw);

            return qw;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="qw"></param>
        public void InitQueryWindow(QueryWindow qw) {
            qw.MdiParent = this;
            qw.FormClosing += new FormClosingEventHandler(RemoveWindowItem);
            qw.Show(this.dockPanel1);

            AddWindowMenuItem(qw, WindowType.Run);
        }

        /// <summary>
        /// Open the query window.
        /// </summary>
        /// <param name="file"></param>
        public QueryWindow OpenQueryWindow(string file) {
            QueryWindow qw = new QueryWindow(file);
            qw.Content = File.ReadAllText(file);

            this.InitQueryWindow(qw);

            return qw;
        }

        public void From1_DragEnter(object sender, DragEventArgs e) {
            if (e.Data.GetDataPresent(DataFormats.FileDrop, false) == true)
                e.Effect = DragDropEffects.All;
        }

        public void RemoveWindowItem(
            object source, FormClosingEventArgs e) {
            DockContent form = source as DockContent;

            foreach (ToolStripItem item in windowToolStripMenuItem.DropDownItems) {
                if (item.Name == form.Text) {
                    windowToolStripMenuItem.DropDownItems.Remove(item);
                    DesktopFormContext.Context.Remove(form);
                    return;
                }
            }
        }

        public bool AddMenuItems(ToolStripMenuItem item, DirectoryInfo di) {
            int index = 1;
            bool c = false;
            foreach (FileInfo ci in di.GetFiles("*.zoom")) {
                c = true;
                ToolStripMenuItem current = new ToolStripMenuItem();

                current.Name = ci.Name.Split('.')[0];
                current.Text = current.Name;
                index++;

                ToolStripMenuItem forRun = new ToolStripMenuItem("&Run");
                forRun.Click += new EventHandler(ForRunMenuItemClick);
                current.DropDownItems.Add(forRun);

                ToolStripMenuItem forEdit = new ToolStripMenuItem("&Edit");
                forEdit.Click += new EventHandler(ForEditMenuItemClick);
                current.DropDownItems.Add(forEdit);

                item.DropDownItems.Add(current);
            }

            foreach (DirectoryInfo sdi in di.GetDirectories()) {
                ToolStripMenuItem i = new ToolStripMenuItem();
                i.Name = sdi.Name;
                i.Text = sdi.Name;
                item.DropDownItems.Add(i);

                FileInfo[] info = sdi.GetFiles("library.ini");
                if (info.Length > 0) {
                    IniFileLight iniFile = new IniFileLight(info[0].FullName);
                    if (iniFile.Sections["overview"] != null) {
                        string icon = iniFile.Sections["overview"]["icon"];
                        if (File.Exists(icon)) {
                            i.Image = Image.FromFile(icon);
                        }
                    }
                }

                if (AddMenuItems(i, sdi)) {
                    c = true;
                } else {
                    item.DropDownItems.Remove(i);
                }
            }

            return c;
        }

        private void exitToolStripMenuItem1_Click(object sender, EventArgs e) {
            this.Close();
        }

        private void exitToolStripMenuItem_Click(object sender, EventArgs e) {

        }

        private void runToolStripMenuItem1_Click(object sender, EventArgs e) {
            Run();
        }

        private int windowCount = 0;

        public void AddWindowMenuItem(
            DockContent form, WindowType type) {
            int index = this.windowCount + 1;

            //ToolStripMenuItem item = new ToolStripMenuItem();
            //item.Name = form.Text;
            //item.Text = "&" + index.ToString() + " " + form.Text;
            //item.Click += new EventHandler(WindowItem_Click);

            //index = windowToolStripMenuItem.DropDownItems.Add(item);
            DesktopFormContext.Context.Add(form);
        }

        private void saveToolStripMenuItem_Click(object sender, EventArgs e) {
            if (this.ActiveMdiChild == null) {
                return;
            }

            IDesktopView dw = this.ActiveMdiChild as IDesktopView;

            if (string.IsNullOrEmpty(dw.GetFileName())) {
                saveAsToolStripMenuItem_Click(sender, e);
            } else {
                dw.Save(dw.GetFileName());
            }
        }

        private void aboutToolStripMenuItem_Click(object sender, EventArgs e) {
            //AboutBox1 f = new AboutBox1();
            AboutBox f = new AboutBox();

            f.ShowDialog();
        }

        private void saveAsToolStripMenuItem_Click(object sender, EventArgs e) {
            IDesktopView dw = (IDesktopView)this.ActiveMdiChild;
            if (dw == null) {
                return;
            }

            string initPath = Utils.ModelPath;
            SaveFileDialog dialog = new SaveFileDialog();

            dialog.Filter = dw.GetFileFilter();
            dialog.InitialDirectory = initPath.Split(';')[0];
            if (dialog.ShowDialog() == DialogResult.OK) {
                string fileName = dialog.FileName.Trim();

                dw.Save(fileName);
            }
        }

        private void forRunToolStripMenuItem_Click(object sender, EventArgs e) {
            string initPath = Utils.ModelPath;
            OpenFileDialog dialog = new OpenFileDialog();

            dialog.Filter = "Zoom Source (*.zoom) | *.zoom";
            dialog.InitialDirectory = initPath;

            if (dialog.ShowDialog() == DialogResult.OK) {
                int lastDot = dialog.FileName.LastIndexOf('.');
                int last = dialog.FileName.LastIndexOf('\\');
                string name = dialog.FileName.Substring(last + 1, lastDot - last - 1);

                OpenRunWindow(name);
            }
        }

        private IDockContent FindDocument(string text) {
            if (dockPanel1.DocumentStyle == DocumentStyle.SystemMdi) {
                foreach (Form form in MdiChildren)
                    if (form.Text == text)
                        return form as IDockContent;

                return null;
            } else {
                foreach (IDockContent content in dockPanel1.Documents)
                    if (content.DockHandler.TabText == text)
                        return content;

                return null;
            }
        }

        private void forEditToolStripMenuItem_Click(object sender, EventArgs e) {
            string initPath = Utils.ModelPath;
            OpenFileDialog dialog = new OpenFileDialog();

            dialog.Filter = "Zoom Source (*.zoom) | *.zoom";
            dialog.InitialDirectory = initPath.Split(';')[0];

            if (dialog.ShowDialog() == DialogResult.OK) {
                if (DesktopFormContext.Context.ContainsKey(dialog.FileName)) {
                    DesktopFormContext.Context[dialog.FileName].BringToFront();
                } else {
                    OpenEditWindow(dialog.FileName);
                }
            }
        }

        public void ForRunMenuItemClick(object source, EventArgs e) {
            ToolStripMenuItem item = (ToolStripMenuItem)source;

            OpenRunWindow(item.OwnerItem.Name);
        }

        public void OpenRunWindow(string className) {
            IDockContent dc = FindDocument(className);
            if (dc != null) {
                dc.OnActivated(new EventArgs());
                return;
            }

            try {
                RunWindow rw = new RunWindow(className);
                rw.MdiParent = this;
                rw.FormClosing += new FormClosingEventHandler(RemoveWindowItem);
                rw.Show(this.dockPanel1);

                //AddWindowMenuItem(rw, WindowType.Run);
            } catch (Exception ex) {
                MessageBox.Show(ex.Message);
            }
        }

        public void ForEditMenuItemClick(object source, EventArgs e) {
            ToolStripMenuItem item = (ToolStripMenuItem)source;

            OpenEditWindow(item.OwnerItem.Name + ".zoom");
        }

        public EditingForm OpenEditWindow(string p) {
            IDockContent dc = FindDocument(p);
            if (dc != null) {
                dc.OnActivated(new EventArgs());
                return null;
            }

            EditingForm editor = null;

            if (!string.IsNullOrEmpty(p)) {
                DefaultClassFinder finder = new DefaultClassFinder();
                int index = p.IndexOf('.');

                string className = p;
                if (index > 0) {
                    className = p.Split('.')[0];
                }
                p = finder.GetLocation(className);

                if (System.IO.File.Exists(p) == false) {
                    MessageBox.Show(className + " does not exist");
                    return null;
                }
                editor = new EditingForm(p);
                editor.Text = p;
            } else {
                untitledCount++;
                editor = new EditingForm();
                editor.Text = "Untitled-" + untitledCount;
                if (File.Exists(DesktopUtils.ModelTemplateFile)) {
                    editor.Source = File.ReadAllText(
                        DesktopUtils.ModelTemplateFile);
                }
            }

            ShowWindow(editor);

            return editor;
        }

        public void ShowWindow(DockContent editor) {
            //if (dockPanel1.DocumentStyle == DocumentStyle.SystemMdi) {
            editor.MdiParent = this;
            editor.FormClosing += new FormClosingEventHandler(
                RemoveWindowItem);
            editor.Show(this.dockPanel1);
            //} else {
            //editor.Show(dockPanel1);
            //}
            AddWindowMenuItem(editor, WindowType.Run);
        }

        public void WindowItem_Click(object source, EventArgs e) {
            ToolStripMenuItem item = (ToolStripMenuItem)source;

            DesktopFormContext.Context[item.Text].BringToFront();
        }

        private void toolStripMenuItem2_Click(object sender, EventArgs e) {
            Cut cut = new Cut();
            Execute(cut);
        }

        public void Execute(AbstractEditAction action) {
            if (this.ActiveMdiChild == null || !(this.ActiveMdiChild is IDesktopView)) {
                return;
            }

            IDesktopView form = (IDesktopView)this.ActiveMdiChild;
            if (form == null) {
                return;
            }

            action.Execute(form.GetTextEditorControl());
        }

        private void pasteToolStripMenuItem_Click(object sender, EventArgs e) {
            Paste paste = new Paste();
            this.Execute(paste);
        }

        private void copyToolStripMenuItem_Click(object sender, EventArgs e) {
            Copy copy = new Copy();
            this.Execute(copy);
        }

        private void toolStripMenuItem3_Click(object sender, EventArgs e) {
            if (this.ActiveMdiChild == null) {
                return;
            }

            SaveFileDialog dialog = new SaveFileDialog();

            dialog.Filter = "HTML Files (*.html)|*.html";
            if (dialog.ShowDialog() == DialogResult.OK) {
                ((IDesktopView)this.ActiveMdiChild).Save(dialog.FileName);
            }
        }

        private void preferencesToolStripMenuItem1_Click(
            object sender, EventArgs e) {
            ShowPreferencesView();
        }

        public void ShowPreferencesView() {
            PreferencesForm form = new PreferencesForm();

            form.ShowDialog();
        }

        private void undoToolStripMenuItem_Click(
            object sender, EventArgs e) {
            Undo undo = new Undo();
            this.Execute(undo);
        }

        private void selectAllToolStripMenuItem_Click(object sender, EventArgs e) {
            SelectWholeDocument selectAll = new SelectWholeDocument();
            Execute(selectAll);
        }

        private void redoToolStripMenuItem_Click(object sender, EventArgs e) {
            Redo redo = new Redo();
            this.Execute(redo);
        }

        private void clearInputToolStripMenuItem_Click(
            object sender, EventArgs e) {
            if (this.ActiveMdiChild != null && this.ActiveMdiChild.GetType() == typeof(RunWindow)) {
                RunWindow rw = (RunWindow)this.ActiveMdiChild;
                rw.ClearInput();
            }
        }

        private void queryToolStripMenuItem_Click(
            object sender, EventArgs e) {
            this.OpenQueryWindow();
        }

        private void tsbSave_Click(object sender, EventArgs e) {
            this.saveToolStripMenuItem_Click(sender, e);
        }

        private void expressionEvaluatorToolStripMenuItem_Click(object sender, EventArgs e) {
            Tools.ExpressionEvaluatorForm f = new Zove.Desktop.Tools.ExpressionEvaluatorForm();

            f.MdiParent = this;
            f.Show();
        }

        private void arrangeWindowsToolStripMenuItem_Click(object sender, EventArgs e) {

        }

        private void closeAllToolStripMenuItem_Click(object sender, EventArgs e) {
            foreach (Form f in this.MdiChildren) {
                f.Close();
            }
        }

        private void classStatisticsToolStripMenuItem_Click(
            object sender, EventArgs e) {
            ClassStatisticsForm f = null;

            if (ActiveMdiChild != null) {
                RuntimeModel rm = null;
                if (ActiveMdiChild.GetType() == typeof(EditingForm)) {
                    EditingForm ef = (EditingForm)ActiveMdiChild;
                    rm = ZoveDependencyManager.Instance.RuntimeModelLoader.LoadByClassName(ef.ClassName);
                } else if (ActiveMdiChild.GetType() == typeof(RunWindow)) {
                    RunWindow rw = (RunWindow)ActiveMdiChild;
                    rm = ZoveDependencyManager.Instance.RuntimeModelLoader.LoadByClassName(rw.ClassName);
                } else {
                    return;
                }

                f = new ClassStatisticsForm(rm);
            } else {
                MessageBox.Show("Please open a class for edit or run to proceed.");
                return;
            }

            f.MdiParent = this;
            f.Show(this.dockPanel1);
        }

        private void messagesToolStripMenuItem_Click(object sender, EventArgs e) {
            if (MessageForm.Instance == null) {
                MessageForm.Instance = new MessageForm();
                //MessageForm.Instance.MdiParent = this;
            }

            MessageForm.Instance.Show(this.dockPanel1, DockState.DockBottom);
        }

        private void rootFinderToolStripMenuItem_Click(object sender, EventArgs e) {
            RootFinderForm f = new RootFinderForm();

            f.MdiParent = this;
            f.Show();
        }

        private void equationSetSolverToolStripMenuItem_Click(object sender, EventArgs e) {
            EquationGroupSolverForm f = new EquationGroupSolverForm();

            f.MdiParent = this;
            f.Show();
        }

        private void forQueryToolStripMenuItem_Click(
            object sender, EventArgs e) {
            OpenFileDialog f = new OpenFileDialog();

            f.Filter = "Zoom Query Language File (*.zql) | *.zql";
            if (f.ShowDialog() == DialogResult.OK) {
                OpenQueryWindow(f.FileName);
            }
        }

        public void CheckModel() {
            if (this.ActiveMdiChild != null
                && this.ActiveMdiChild.GetType().Equals(typeof(EditingForm))) {
                EditingForm f = (EditingForm)this.ActiveMdiChild;

                //try {
                IRuntimeModelLoader loader
                    = ZoveDependencyManager.Instance.RuntimeModelLoader;
                //loader.GetLogger().ClearAll();

                RuntimeModel rm = loader.LoadBySource(f.Source);
                //if (loader.GetLogger().GetErrorMessages().Count > 0) {
                //    if (MessageForm.Instance == null) {
                //        MessageForm.Instance = new MessageForm();
                //        MessageForm.Instance.MdiParent = this;
                //    }

                //    MessageForm.Instance.ShowMessages(
                //        "Errors", loader.GetLogger().GetErrorMessages());
                //    return;
                //} else {
                //    MessageBox.Show("The model is well defined.");
                //}
                MessageBox.Show("The model is well structured.");
                //} catch (Exception ex) {
                //    MessageBox.Show(ex.Message);
                //}
            }
        }

        private void tsCheckModel_Click(object sender, EventArgs e) {
            CheckModel();
        }

        private void checkToolStripMenuItem_Click(
            object sender, EventArgs e) {
        }

        private void toolStripMenuItem5_Click(
            object sender, EventArgs e) {
            if (this.ActiveMdiChild != null) {
                this.ActiveMdiChild.Close();
            }
        }

        private void toolStripButton1_Click(
            object sender, EventArgs e) {
            OpenQueryWindow();
        }

        private void modelToolStripMenuItem_Click(
            object sender, EventArgs e) {
            AddModelDialog();
        }

        public string AddModelDialog() {
            return this.AddModelDialog(string.Empty);
        }

        public string AddModelDialog(string folder) {
            AddModelDialog d = null;

            if (string.IsNullOrEmpty(folder)) {
                d = new AddModelDialog();
            } else {
                d = new AddModelDialog(folder);
            }

            if (d.ShowDialog() == DialogResult.OK) {
                string fileName = string.Empty;

                if (!string.IsNullOrEmpty(d.Directory)) {
                    fileName = d.Directory.EndsWith("\\") ?
                        d.Directory + d.ModelName + ".zoom"
                        : d.Directory + "\\" + d.ModelName + ".zoom";
                    File.WriteAllText(fileName, d.Model);
                }

                EditingForm editor = null;
                if (string.IsNullOrEmpty(fileName)) {
                    editor = new EditingForm();
                } else {
                    editor = new EditingForm(fileName);
                }

                ShowWindow(editor);

                return fileName;
            }

            return string.Empty;
        }

        private void programToolStripMenuItem_Click(object sender, EventArgs e) {
            AddProgrammingDialog();
        }

        public string AddProgrammingDialog() {
            return this.AddProgrammingDialog(
                string.Empty, DialogType.Program);
        }

        public string AddProgrammingDialog(
            string folder, DialogType type) {
            AddProgramDialog d = null;

            if (string.IsNullOrEmpty(folder)) {
                d = new AddProgramDialog(type);
            } else {
                d = new AddProgramDialog(folder, type);
            }

            if (d.ShowDialog() == DialogResult.OK) {
                ProgrammingEditor pe = new ProgrammingEditor();

                if (File.Exists(DesktopUtils.ProgramTemplateFile)) {
                    pe.Source = File.ReadAllText(
                        DesktopUtils.ProgramTemplateFile);
                }

                ShowWindow(pe);

                return d.FileName;
            }

            return string.Empty;
        }

        public void OpenProgrammingWindow(string fileName) {
            ProgrammingEditor pe = new ProgrammingEditor(fileName);

            ShowWindow(pe);
        }

        private void queryToolStripMenuItem1_Click(object sender, EventArgs e) {
            OpenQueryWindow();
        }

        private void programmingToolStripMenuItem_Click(object sender, EventArgs e) {
            OpenFileDialog f = new OpenFileDialog();

            if (f.ShowDialog() == DialogResult.OK) {
                ProgrammingEditor pe = new ProgrammingEditor(f.FileName);

                ShowWindow(pe);
            }
        }

        private void interactiveModeToolStripMenuItem_Click(object sender, EventArgs e) {
            ShowInteractiveWorkbench();
        }

        private void ShowInteractiveWorkbench() {
            try {
                InteractiveWorkBench i = new InteractiveWorkBench();

                i.MdiParent = this;
                i.Show(this.dockPanel1);
            } catch (Exception e) {
                MessageBox.Show(e.Message);
            }
        }

        private void toolStripMenuItem6_Click(object sender, EventArgs e) {
            Delete action = new Delete();
            this.Execute(action);
        }

        private List<string> recentFiles = new List<string>();

        /// <summary>
        /// 
        /// </summary>
        /// <param name="fileName"></param>
        public void AddRecentFile(string fileName) {
            this.recentFiles.Add(fileName);
            string files = ConfigurationManager.AppSettings["recent files"];
            files = files + ";" + fileName;
            ConfigurationManager.AppSettings["recent files"] = files;
        }

        public void OpenFile() {
            string initPath = Utils.ModelPath;
            OpenFileDialog dialog = new OpenFileDialog();

            dialog.Filter = "All Zoom Files (*.zoom; *.fpz; *.zql)|*.zoom;*.fpz;*.zql|Modeling Files (*.zoom) |*.zoom|Programming Files (*.fpz)|*.fpz|Query Files (*.zql)|*.zql|OML Files (*.oml)|*.oml|Text Files (*.txt)|*.txt|INI Files (*.ini)|*.ini|XML Files (*.xml)|*.xml|All Files (*.*)|*.*";
            dialog.InitialDirectory = initPath;
            dialog.CheckFileExists = true;
            dialog.CheckPathExists = true;

            if (dialog.ShowDialog() == DialogResult.OK) {
                int lastDot = dialog.FileName.LastIndexOf('.');
                int last = dialog.FileName.LastIndexOf('\\');

                string extension = string.Empty;
                string fileName = dialog.FileName;

                if (lastDot > 0) {
                    fileName = dialog.FileName.Substring(last + 1, lastDot - last - 1);
                    extension = dialog.FileName.Substring(lastDot, dialog.FileName.Length - lastDot);
                }

                switch (extension) {
                    case ".zoom":
                        OpenEditWindow(fileName);
                        break;
                    case ".fpz":
                        OpenProgrammingWindow(dialog.FileName);
                        break;
                    case ".fp":
                        OpenProgrammingWindow(dialog.FileName);
                        break;
                    case ".zql":
                        OpenQueryWindow(dialog.FileName);
                        break;
                    case ".oml":
                        OpenOMLWindow(dialog.FileName);
                        break;
                    case ".txt":
                        OpenTextEditWindow(dialog.FileName, "Text");
                        break;
                    case ".xml":
                        OpenTextEditWindow(dialog.FileName, "Xml");
                        break;
                    default:
                        OpenTextEditWindow(dialog.FileName, "Text");
                        break;
                }

                this.AddRecentFile(dialog.FileName);
            }
        }

        private void openToolStripMenuItem_Click(object sender, EventArgs e) {

        }

        public TextEditor OpenTextEditWindow(string p, string type) {
            TextEditor te = new TextEditor(p, type);

            ShowWindow(te);

            return te;
        }

        protected OMLEditor OpenOMLWindow(string fileName) {
            OMLEditor oe = new OMLEditor(fileName);

            this.ShowWindow(oe);

            return oe;
        }

        private void toolStripMenuItem7_Click(object sender, EventArgs e) {
            foreach (Form f in this.MdiChildren) {
                if (f is IDesktopView) {
                    IDesktopView idf = f as IDesktopView;
                    if (string.IsNullOrEmpty(idf.GetFileName())) {
                        OpenFileDialog d = new OpenFileDialog();

                        if (d.ShowDialog() == DialogResult.OK) {
                            idf.Save(d.FileName);
                        }
                    } else {
                        idf.Save(idf.GetFileName());
                    }
                }
            }
        }

        private void oMLToolStripMenuItem_Click(object sender, EventArgs e) {
            OMLEditor oe = new OMLEditor();

            this.ShowWindow(oe);
        }

        private void toolbarToolStripMenuItem_Click(object sender, EventArgs e) {
            this.toolStrip1.Visible = this.toolbarToolStripMenuItem.Checked = !this.toolbarToolStripMenuItem.Checked;
            DesktopUtils.ShowToolBar = this.statusStrip1.Visible;
        }

        private void statusbarToolStripMenuItem_Click(object sender, EventArgs e) {
            this.statusStrip1.Visible = this.statusbarToolStripMenuItem.Checked = !this.statusbarToolStripMenuItem.Checked;
            DesktopUtils.ShowStatusBar = this.statusStrip1.Visible;
        }

        private void helpToolStripMenuItem1_Click(
            object sender, EventArgs e) {
            //ZoomDocuViewer viewer = new ZoomDocuViewer();

            //viewer.MdiParent = this;
            //viewer.Show(this.dockPanel1);
        }

        public void Form_Load(object sender, EventArgs e) {
            this.toolbarToolStripMenuItem.Checked = this.toolStrip1.Visible = DesktopUtils.ShowToolBar;
            this.statusbarToolStripMenuItem.Checked = this.statusStrip1.Visible = DesktopUtils.ShowStatusBar;
            if (!string.IsNullOrEmpty(
                DesktopUtils.DefaultWorkspace)) {
                ShowWorkspace(DesktopUtils.DefaultWorkspace);
            }

            foreach(string fileName in this.recentFiles) {
                ToolStripMenuItem item = new ToolStripMenuItem(fileName);
                //this.itemRecentFiles.DropDownItems.Add(item);

                item.Click += new EventHandler(item_Click);
            }

            DesktopFormContext.Context.BreakPoints
                = SerializationHelper.Deserialize(
                Environment.CurrentDirectory + "\\breakpoints.xml");
        }

        public void item_Click(object sender, EventArgs e) {
            ToolStripMenuItem item = sender as ToolStripMenuItem;

            if (item.Text.EndsWith(".fpz")) {
                OpenProgrammingWindow(item.Text);
            }
        }

        private void toolStripMenuItem8_Click(object sender, EventArgs e) {
            //this.tsbWorkspace.Checked = !this.tsbWorkspace.Checked;
            //SolutionWindow.Instance.Visible = this.tsbWorkspace.Checked;

            SolutionWindow sw = new SolutionWindow(
                DesktopUtils.ModelPool.Split(';')[0]);

            sw.MdiParent = this;
            sw.Show(this.dockPanel1);
            sw.DockState = DockState.DockLeft;
        }

        private void tsImport_Click(object sender, EventArgs e) {

        }

        private void workspaceToolStripMenuItem_Click(object sender, EventArgs e) {
            OpenWorkspaceWindow w = new OpenWorkspaceWindow();

            if (w.ShowDialog() == DialogResult.OK) {
                ZoveDependencyManager.Instance.ClassFinder.AddClassPath(
                    w.SelectedPath);
                SolutionWindow sw = ShowWorkspace(w.SelectedPath);
                DesktopFormContext.Context.Main.WorkspaceWindowCollection.Add(sw);
            }
        }

        public SolutionWindow ShowWorkspace(string workspaceDir) {
            SolutionWindow s = new SolutionWindow(workspaceDir);

            s.MdiParent = DesktopFormContext.Context.Main;
            s.Show(this.dockPanel1);
            s.DockState = DockState.DockLeft;

            return s;
        }

        private void fileToolStripMenuItem1_Click(object sender, EventArgs e) {
            this.OpenFile();
        }

        protected void Run() {
            if (this.ActiveMdiChild != null
                && this.ActiveMdiChild is IRunnableView) {
                ((IRunnableView)this.ActiveMdiChild).Run();
            }
        }

        protected void Debug() {
            if (this.ActiveMdiChild != null
                && this.ActiveMdiChild is IDebuggableView) {
                ((IDebuggableView)this.ActiveMdiChild).StartDebugging();
            }
        }

        private void tsbRun_Click(object sender, EventArgs e) {
            if (cmdDebug.Text == "Run") {
                runInBackgroundToolStripMenuItem_Click(sender, e);
            }
        }

        private void functionManagerToolStripMenuItem_Click(object sender, EventArgs e) {
            FunctionManager fm = new FunctionManager();

            fm.Show();
        }

        private void tsbOpen_Click(object sender, EventArgs e) {
            this.OpenFile();
        }

        private void tsbInterativeWorkbench_Click(object sender, EventArgs e) {
            ShowInteractiveWorkbench();
        }

        public WorkspaceWindowCollection WorkspaceWindowCollection {
            get;
            set;
        }

        private void cancelToolStripMenuItem_Click(object sender, EventArgs e) {
            Cancel();
        }

        public void Cancel() {
            if (this.ActiveMdiChild != null
                &&
                this.ActiveMdiChild is ICancellable) {
                ((ICancellable)this.ActiveMdiChild).Cancel();
            }
        }

        private void addExecutableToolStripMenuItem_Click(object sender, EventArgs e) {
            ExecutableManager mgr = new ExecutableManager();
            if (mgr.ShowDialog() == DialogResult.OK) {
            }
        }

        private void optimizationModellingLanguageToolStripMenuItem_Click(object sender, EventArgs e) {
            OMLEditor omlEditor = new OMLEditor();

            ShowWindow(omlEditor);
        }

        private void plainTextToolStripMenuItem_Click(object sender, EventArgs e) {
            AddProgramDialog d = new AddProgramDialog();

            if (d.ShowDialog() == DialogResult.OK) {
                EditingForm editor = new EditingForm();

                ShowWindow(editor);
            }
        }

        private void xMLToolStripMenuItem_Click(object sender, EventArgs e) {
            AddProgramDialog d = new AddProgramDialog();

            if (d.ShowDialog() == DialogResult.OK) {
                EditingForm editor = new EditingForm();

                ShowWindow(editor);
            }
        }

        private void toolStripButton2_Click(object sender, EventArgs e) {
            this.Cancel();
        }

        private void queryToolStripMenuItem_Click_1(object sender, EventArgs e) {
            OpenQueryWindow();
        }

        private void modellingToolStripMenuItem_Click(object sender, EventArgs e) {
            AddModelDialog();
        }

        private void programmingToolStripMenuItem_Click_1(object sender, EventArgs e) {
            AddProgrammingDialog();
        }

        private void fileDiffToolStripMenuItem_Click(object sender, EventArgs e) {
            MainForm mf = new MainForm();

            mf.ShowDialog();
        }

        private void databaseQueryViewToolStripMenuItem_Click(object sender, EventArgs e) {
            DatabaseLoginView view = new DatabaseLoginView();

            if (view.ShowDialog() == DialogResult.OK) {
                DatabaseQueryView queryView = new DatabaseQueryView();

                ShowWindow(queryView);
            }
        }

        private void taskListToolStripMenuItem_Click(object sender, EventArgs e) {
            TaskView view = new TaskView();

            view.Show(this.dockPanel1);
            view.DockState = DockState.DockBottom;
        }

        private void bookmarkWindowToolStripMenuItem_Click(object sender, EventArgs e) {
            if (this.ActiveMdiChild != null
                && this.ActiveMdiChild is IDesktopView) {
                IDesktopView desktopForm = this.ActiveMdiChild as IDesktopView;
                BookmarkView view = new BookmarkView(
                    desktopForm);

                view.Show(dockPanel1);
                view.DockState = DockState.DockBottom;
            }
        }

        private void webBrowserToolStripMenuItem_Click(object sender, EventArgs e) {
            EmbeddedWebBrowser b = new EmbeddedWebBrowser();

            b.Show(dockPanel1);
            b.DockState = DockState.DockLeft;
        }

        private void systemToolStripMenuItem_Click(object sender, EventArgs e) {
            MessageForm f = new MessageForm();

            f.DockAreas = DockAreas.DockBottom;

            ShowWindow(f);
        }

        private void outputWindowToolStripMenuItem_Click(object sender, EventArgs e) {
            ConsoleWindow w = new ConsoleWindow();

            ShowWindow(w);
        }

        private void runInBackgroundToolStripMenuItem_Click(object sender, EventArgs e) {
            if (this.ActiveMdiChild != null
                && this.ActiveMdiChild is IDebuggableView) {
                IDebuggableView view = this.ActiveMdiChild as IDebuggableView;
                switch (view.State) {
                    case DebuggingState.Idle:
                        view.StartDebugging();
                        break;
                    case DebuggingState.Breaked:
                        view.Resume();
                        break;
                    case DebuggingState.Running:
                        view.Break();
                        break;
                    default:
                        break;
                }
            }
        }

        private void functionsNavigatorToolStripMenuItem_Click(
            object sender, EventArgs e) {
            FunctionManager view = new FunctionManager();
            ShowWindow(view);
        }

        private void modelNavigatorToolStripMenuItem_Click(object sender, EventArgs e) {
        }

        private void quickFindToolStripMenuItem_Click(object sender, EventArgs e) {
            FindView v = new FindView();

            v.ShowDialog();
        }

        private void goToToolStripMenuItem1_Click(object sender, EventArgs e) {
            AbstractDesktopForm f = this.ActiveMdiChild as AbstractDesktopForm;
            GotoView d = new GotoView();

            if (d.ShowDialog() == DialogResult.OK) {
                if (f != null && d.LineNumber >= 0) {
                    f.GetTextEditorControl().ActiveTextAreaControl.TextArea.Caret.Line = d.LineNumber;
                }
            }
        }

        private void quickReplaceToolStripMenuItem_Click(object sender, EventArgs e) {
            ReplaceView v = new ReplaceView();

            if (v.ShowDialog() == DialogResult.OK) {

            }
        }

        private void breakpointsToolStripMenuItem_Click(object sender, EventArgs e) {
            BreakpointView view = new BreakpointView();

            view.Show(this.dockPanel1);
            view.DockState = DockState.DockBottom;
        }

        private void toolStripMenuItem11_Click(object sender, EventArgs e) {

        }

        private void tslStartWithoutDebugging_Click(object sender, EventArgs e) {
            Run();
        }

        private void toolStripMenuItem12_Click(object sender, EventArgs e) {
            if (this.ActiveMdiChild != null && this.ActiveMdiChild is IDebuggableView) {
                IDebuggableView d = this.ActiveMdiChild as IDebuggableView;
                LocalView view = new LocalView(d.Context);

                view.Show(this.dockPanel1);
                view.DockState = DockState.DockBottom;
            }
        }

        /// <summary>
        /// Store the break points
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Form1_FormClosing(object sender, EventArgs e) {
            try {
                SerializationHelper.Serialize(
                    DesktopFormContext.Context.BreakPoints,
                    Environment.CurrentDirectory + "\\breakpoints.xml");
            } catch (IOException) {
            }
        }

        private void validateToolStripMenuItem_Click(object sender, EventArgs e) {
            CheckModel();
        }

        private void listInvovledClassesToolStripMenuItem_Click(object sender, EventArgs e) {
            if (this.ActiveMdiChild != null
                && this.ActiveMdiChild.GetType().Equals(typeof(EditingForm))) {
                EditingForm f = (EditingForm)this.ActiveMdiChild;

                //try {
                IRuntimeModelLoader loader
                    = ZoveDependencyManager.Instance.RuntimeModelLoader;
                //loader.GetLogger().ClearAll();
                DefaultRuntimeModelLoader l = loader as DefaultRuntimeModelLoader;

                l.AssociatedClasses.Clear();
                RuntimeModel rm = loader.LoadBySource(f.Source);

                List<Zove.Runtime.DefaultRuntimeModelLoader.AssociatedClass> classes = new List<DefaultRuntimeModelLoader.AssociatedClass>();

                foreach (string key in l.AssociatedClasses.Keys) {
                    Zove.Runtime.DefaultRuntimeModelLoader.AssociatedClass c = l.AssociatedClasses[key];
                    classes.Add(c);
                }

                AssociatedClassesView view = new AssociatedClassesView(classes);
                view.Show(this.dockPanel1);
                view.DockState = DockState.DockBottom;
            }
        }

        private void itemProfile_Click(object sender, EventArgs e) {
            if (this.ActiveMdiChild != null && this.ActiveMdiChild is IProfileable) {
                IProfileable p = (IProfileable)this.ActiveMdiChild;

                double ret = p.Profile();

                MessageBox.Show(ret.ToString());
            }
        }

        private void outputToolStripMenuItem_Click(object sender, EventArgs e) {
            if (this.ActiveMdiChild != null && this.ActiveMdiChild is IDebuggableView) {
                IDebuggableView d = this.ActiveMdiChild as IDebuggableView;
                CallStackView view = new CallStackView(d.Context);

                view.Show(this.dockPanel1);
                view.DockState = DockState.DockBottom;
            }
        }

        private void itemStepInto_Click(object sender, EventArgs e) {
            if (this.ActiveMdiChild != null && this.ActiveMdiChild is IDebuggableView) {
                IDebuggableView d = this.ActiveMdiChild as IDebuggableView;
                d.StepInto();
            }
        }

        private void itemStepOver_Click(object sender, EventArgs e) {
            if (this.ActiveMdiChild != null && this.ActiveMdiChild is IDebuggableView) {
                IDebuggableView d = this.ActiveMdiChild as IDebuggableView;
                d.StepInto();
            }
        }

        private void itemDeleteAllBreakpoints_Click(object sender, EventArgs e) {
        }

        private void itemDisableAllBreakpoints_Click(object sender, EventArgs e) {

        }

        private void itemSetupBreakpoint_Click(object sender, EventArgs e) {
            SetupBreakpointView view = new SetupBreakpointView();

            if (view.ShowDialog() == DialogResult.OK) {

            }
        }

        public Project Project {
            get;
            set;
        }

        private void itemNewProject_Click(object sender, EventArgs e) {
            NewProjectView view = new NewProjectView();

            if (view.ShowDialog() == DialogResult.OK) {

            }
        }

        private void tbtnPreferences_Click(object sender, EventArgs e) {
            ShowPreferencesView();
        }

        public class ServerInfo {
            public string Name {
                get;
                set;
            }

            public string Location {
                get;
                set;
            }

            public bool Status {
                get;
                set;
            }
        }

        private void toolStripMenuItem13_Click(object sender, EventArgs e) {
            List<ServerInfo> servers = new List<ServerInfo>();
            servers.Add(new ServerInfo() { Name = "Production 1", Location = "http://prod.zove.com", Status = true });
            ServerManagerView view = new ServerManagerView(servers);

            view.Show(this.dockPanel1);
            view.DockState = DockState.DockBottom;
        }

        private void preferencesToolStripMenuItem1_Click_1(object sender, EventArgs e) {
            ShowPreferencesView();
        }

        private void toolStripMenuItem10_Click(object sender, EventArgs e) {
            WatchView view = new WatchView();

            view.Show(this.dockPanel1);
            view.DockState = DockState.DockBottom;
        }

        private void itemToggleBreakpoint_Click(object sender, EventArgs e) {

        }

        private void toolStripMenuItem3_Click_1(object sender, EventArgs e) {

        }

        private void itemPrint_Click(object sender, EventArgs e) {
            PrintDialog p = new PrintDialog();

            if (p.ShowDialog() == DialogResult.OK) {
                if (DesktopFormContext.Context.Main.ActiveMdiChild is IDesktopView) {
                }
            }
        }

        private void btnRestart_Click(object sender, EventArgs e) {
            Restart();
        }

        private void Restart() {
            if (this.ActiveMdiChild != null
                && this.ActiveMdiChild is IDebuggableView) {
                ((IDebuggableView)this.ActiveMdiChild).Restart();
            }
        }

        private void btnExecute_Click(object sender, EventArgs e) {
            Run();
        }

        public void SwitchDebuggingMode(DebuggingState state) {
            switch (state) {
                case DebuggingState.Running:
                    cmdDebug.Text = "Break";
                    cmdDebug.Image = Properties.Resources.vm_suspend;
                    break;
                case DebuggingState.Breaked:
                    cmdDebug.Text = "Continue";
                    cmdDebug.Image = Properties.Resources.Run;
                    break;
                case DebuggingState.Stopped:
                    cmdDebug.Text = "Run";
                    cmdDebug.Image = Properties.Resources.Run;
                    break;
                default:
                    cmdDebug.Text = "Run";
                    cmdDebug.Image = Properties.Resources.Run;
                    break;
            }
        }

        private void tsbCut_Click(object sender, EventArgs e) {
            Cut c = new Cut();
            Execute(c);
        }

        private void tsbCopy_Click(object sender, EventArgs e) {
            Copy c = new Copy();
            Execute(c);
        }

        private void tsbPaste_Click(object sender, EventArgs e) {
            Paste paste = new Paste();
            Execute(paste);
        }

        private void cmdPlotExplorer_Click(object sender, EventArgs e) {
            PlotExplorerView view = new PlotExplorerView();

            view.Show(this.dockPanel1);
            view.DockState = DockState.DockRight;
        }
    }
}
